import './channel.scss'
import {SettingFilled,} from '@ant-design/icons';
import type { CollapseProps, } from 'antd';
import { Collapse, Dropdown, message, Tooltip} from 'antd';
import ChannelItem from './components/ChannelItem';
import { useEffect, useRef, useState } from 'react';

import { setChannelId, setServerId } from '../../store/modules/channelStore';
import { useAppDispatch, useAppSelector } from '../../utils/storeHook/storeHook';
import http from '../../utils/http';
import api from '../../api';
import CreateChannel from './components/CreateChannel';
import { createUserDropdownStyles, defaultTheme } from '../../static/styles/dropDown'
import socketService from "../../services/socketService"; // 导入服务
import TextChat from '../TextChat/TextChat';
import { VoiceChat, MyDialog, MyButton, MyInput, CopyBtn, ConfirmDialog, User } from '../../components'

interface ServerUsers {
    avatar_url: string,
    username: string,
    user_id:string,
    server_id:string,
    role:string,
    joined_at:string,
    guest_id:string,
    membership_id:string,
    can_leave:boolean,
    status:string,
    dropDownVis:boolean,
    isFriend: boolean,
}

interface ChatT {
    channel_id:string,
    name:string,
    position:number,
    server_id:string,
    type:string,
    created_at:string
}

interface userServerInfo {
    server_id:string,
    server_name:string,
    role:string,
    can_leave:boolean,
    user_id:string,
    username:string,
    actChannel:string,
    actChannelType:string,
}

interface dropDownItem {
    key:string,
    label?:string,
    type?:string,
    disabled?:boolean,
    onClick?:()=>void
}



function Channel(){
    const dispatch = useAppDispatch()

    const [messageApi, contextHolder] = message.useMessage()
    const styles = createUserDropdownStyles(defaultTheme)
    const [isHovered, setIsHovered] = useState<string | null>(null);

    const actServerId = useAppSelector(state=>state.channel.actServerId)
    const actChannelId = useAppSelector(state=>state.channel.actChannelId)
    const isConnect = useAppSelector(state=>state.server.isConnect)
    const userType = useAppSelector(state=>state.auth.userType)

    const [chatType,setChatType] = useState('text')
    const [textChatList,setTextchatList] = useState<ChatT[]>([])
    const [voiceList,setVoiceList] = useState<ChatT[]>([])
    const [serverInviteCode,setServerInviteCode] = useState('')
    const [userServerInfo,setUserServerInfo] = useState<userServerInfo | null>()
    const [inviteDlgVis,setInviteDlgVis] = useState(false)
    const [changeServerNameDlgVis,setChangeServerNameDlgVis] = useState(false)
    const [addChannelDlgVis,setAddChannelDlgVis] = useState(false)
    const [exitServerDlgVis,setExitServerDlgVis] = useState(false)
    const [settingDropdownVis,setSettingDropdownVis] = useState(false)
    const [newServerName,setNewServerName] = useState('')

    const [userCollapse,setuserCollapse] = useState<CollapseProps['items']>([])

    const channelMember = useRef<ServerUsers[]>([]);
    const settingDropdownRef = useRef<HTMLDivElement>(null);

    const channelSettings:dropDownItem[] = [
        {
            key: '1',
            label: '创建新频道',
            onClick:()=>{
                setAddChannelDlgVis(true)
                setSettingDropdownVis(false)
            },
            disabled:userServerInfo?.role == 'member'
        },
        {
            key: '2',
            label: '修改群组名称',
            onClick:()=>{
                setChangeServerNameDlgVis(true)
                setSettingDropdownVis(false)
            },
            disabled:userServerInfo?.role == 'member'
        },
        {
            key: '10',
            type: 'divider',
        },
        {
            key: '11',
            label: '邀请其他人',
            onClick:getInviteCode
        },
        {
            key: '20',
            type: 'divider',
        },
        {
            key: '21',
            label: userServerInfo?.role=='owner'?'释放群组':'退出群组',
            type: 'danger',
            disabled: !userServerInfo?.can_leave,
            onClick:()=>{
                setExitServerDlgVis(true)
                setSettingDropdownVis(false)
            }
        },
    ]
    const getItemStyle = (item:dropDownItem) => {
        const baseStyle = styles.listItem;
        let style = { ...baseStyle };

        // 处理伪类状态
        if (isHovered === item.key) {
            style = { ...style, ...baseStyle.hover };
        }

        // 处理特殊类型
        if (item.type === 'danger') {
            style = { ...style, ...baseStyle.danger };
            if (isHovered === item.key) {
                style = { ...style, ...baseStyle.danger?.hover };
            }
        }

        if (item.disabled) {
            style = { ...style, ...baseStyle.disabled };
        }

        if(item.type === 'divider'){
            style = styles.divider
        }

        return style;
    };

    function getInviteCode(){
        http.post(api.server.getInviteCode,{server_id:actServerId}).then(res=>{
            setServerInviteCode(res.data.invite_code)
            setInviteDlgVis(true)
            setSettingDropdownVis(false)
        })
    }

    function changeActSC(channelItem:ChatT){
        http.post(api.server.changeActSC,{server_id:actServerId,channel_id:channelItem.channel_id,userType:userType}).then(()=>{
            socketService.offDelMessage()
            socketService.offNewMessage()
            dispatch(setChannelId(channelItem.channel_id))
            if(channelItem.type == 'text'){
                setChatType('text')
            }else if(channelItem.type == 'voice'){
                setChatType('voice')
            }
        })
    }

    function getChannelList(){
        http.post(api.server.getChannelList,{actServerId}).then(res=>{
            const resData = res.data
            setTextchatList(resData.channelList.filter((item:ChatT)=>item.type == 'text').sort((a:ChatT,b:ChatT)=>a.position - b.position))
            setVoiceList(resData.channelList.filter((item:ChatT)=>item.type == 'voice').sort((a:ChatT,b:ChatT)=>a.position - b.position))
            const serverUserList = resData.memberList.map((item:ServerUsers)=>{
                if(item.guest_id){
                    item.username = '游客' + item.guest_id.slice(-4)
                }
                item.dropDownVis = false
                return item
            })
            setuserCollapse([
            {
                key: '1',
                label: '用户列表',
                children: serverUserList.map((item:ServerUsers)=>{ 
                    return (
                        <User 
                            userItem={item} 
                            key={item.user_id || item.guest_id}
                        />)
                    }),
                },
            ])
            channelMember.current = serverUserList
        })
    }

    function changeServerName(){
        http.post(api.server.changeServerName,{server_id:actServerId,server_name:newServerName,}).then(()=>{
            setNewServerName('')
            setChangeServerNameDlgVis(false)
            messageApi.success('修改成功')
        }).catch(err=>{
            messageApi.error(err.message)

        })
    }

    function disableChannel(item:ChatT){
        if(item.type == 'voice' && userType == 'guestUser'){
            return true
        }
        return false
    }

    function getUserServerInfo(){
        http.post(api.server.getUserServerInfo,{server_id:actServerId,userType:userType}).then(res=>{
            const resData = res.data
            setUserServerInfo(resData)
            
            dispatch(setChannelId(resData.actChannel))
            if(resData.actChannelType == 'text'){
                setChatType('text')
            }else if(resData.actChannelType == 'voice'){
                setChatType('voice')
            }
        }).catch(err=>{
            messageApi.error(err.message)
        })
    }

    function exitServer(){
        if(userServerInfo?.role == 'owner'){
            messageApi.error('不能退出群组')
        }
        else{
            http.post(api.server.exitServer,{server_id:actServerId}).then(res=>{
                messageApi.success(`成功退出${res.data.name}群组`)
                dispatch(setServerId('server_default'))
            }).catch(err=>{
                messageApi.error(err.message)
            })

        }
    }

    function renewChannel(){
        getChannelList()
        getUserServerInfo()
        messageApi.success('操作成功')
    }

    function handleChangeUserStatus({onlineUsers,stealthUser}:{onlineUsers:string[],stealthUser:string[]}){
        const members = channelMember.current.map(item=>{
            return {...item,status:'offline'}
        })
        
        onlineUsers.forEach(userId=>{
            const index = members.findIndex(item=>item.user_id == userId)
            const Cindex = channelMember.current.findIndex(item=>item.guest_id == userId)
            
            if(index != -1){
                members[index].status = 'online'
            }
            if(Cindex != -1){
                members[Cindex].status = 'online'
            }
        })
        stealthUser.forEach(userId=>{
            const index = members.findIndex(item=>item.user_id == userId)
            const Cindex = channelMember.current.findIndex(item=>item.guest_id == userId)
            if(index != -1){
                members[index].status = 'idle'
            }
            if(Cindex != -1){
                members[Cindex].status = 'idle'
            }
        })
    }

    useEffect(()=>{
        if(isConnect){
            socketService.onUserStatus(handleChangeUserStatus)
        }
        return ()=>{
            socketService.offUserStatus()
        }
    },[isConnect])

    useEffect(()=>{
        if(actServerId == 'notice' || actServerId == 'private') return
        getChannelList()
        getUserServerInfo()
    },[actServerId])
    return (
        <>
            {contextHolder}
            <div className="channel_box">
                <div className='channel_left'>
                    <div className='channel_left_top'>
                        <div className='channel_name'>{userServerInfo?.server_name}</div>
                            <Dropdown 
                                placement="bottomRight" 
                                menu={{}}
                                arrow={{ pointAtCenter: true }}
                                open={settingDropdownVis}
                                destroyOnHidden={true}
                                popupRender={() => (
                                    <div 
                                        style={styles.list}
                                        tabIndex={0}
                                        onBlur={()=>setSettingDropdownVis(false)}
                                        ref={settingDropdownRef}
                                    >
                                        {channelSettings.map(item=>(
                                            !item.disabled&&<div
                                                onClick={item.onClick} style={getItemStyle(item)}
                                                key={item.key}
                                                onMouseEnter={() => !item.disabled && setIsHovered(item.key)}
                                                onMouseLeave={() => setIsHovered(null)}
                                            >{item.label}</div>
                                        ))}
                                    </div>
                                )}
                            >
                                <div 
                                    className='channel_setting' 
                                    onClick={()=>{
                                        setSettingDropdownVis(!settingDropdownVis)
                                        setTimeout(()=>settingDropdownRef.current?.focus(),1)
                                    }}
                                >
                                    <SettingFilled />
                                </div>
                            </Dropdown>
                    </div>
                    <div className='channel_left_channels'>
                        <div className='channel_textChatList'>
                            <div className='channel_item_name'>
                                <span>文字频道</span>
                                {userServerInfo?.role=='owner'&&<Tooltip title="创建新频道">
                                    <div className='channel_item_add' onClick={()=>setAddChannelDlgVis(true)}>
                                        +
                                    </div>
                                </Tooltip>}
                            </div>
                            {
                                textChatList.map((item)=><ChannelItem 
                                    channelItem={item}
                                    key={item.channel_id}
                                    onClick={()=>changeActSC(item)}
                                    role={userServerInfo?.role}
                                    reNewChannelList={()=>renewChannel()}
                                ></ChannelItem>)
                            }
                        </div>
                        <div className='channel_voiceChatList'>
                            <div className='channel_item_name'>
                                <span>语音频道</span>
                                {userServerInfo?.role=='owner'&&<Tooltip title="创建新频道">
                                    <div className='channel_item_add' onClick={()=>setAddChannelDlgVis(true)}>
                                        +
                                    </div>
                                </Tooltip>}
                            </div>
                            {
                                voiceList.map((item)=><ChannelItem 
                                    channelItem={item}
                                    key={item.channel_id}
                                    onClick={()=>changeActSC(item)}
                                    disabled={disableChannel(item)}
                                    role={userServerInfo?.role}
                                    reNewChannelList={()=>renewChannel()}
                                ></ChannelItem>)
                            }
                        </div>
                    </div>
                    <div className='channel_left_onlineUsers' key={actChannelId}>
                        <Collapse 
                            items={userCollapse} 
                            bordered={false} 
                            defaultActiveKey={['1']}
                            className='channel_left_cls'
                        />
                    </div>
                </div>
                <div className='channel_right'>
                    {chatType == 'text'?
                        <TextChat key={actChannelId} actChannelId={actChannelId}></TextChat>:
                        <VoiceChat key={actChannelId} actChannelId={actChannelId}></VoiceChat>
                    }
                </div>
            </div>
            <MyDialog title='邀请好友' visible={inviteDlgVis} onClose={()=>setInviteDlgVis(false)}>
                <div className='invite_code_box'>
                    <div className='invite_code_tips'>
                        分享此邀请码给好友，让好友加入该群组
                    </div>
                    <div className='invite_code'>
                        <span className='invite_code_text'>{serverInviteCode}</span>
                        <CopyBtn copyText={serverInviteCode}></CopyBtn>
                    </div>
                </div>
            </MyDialog>
            <MyDialog visible={changeServerNameDlgVis} title='修改群组名称' onClose={()=>setChangeServerNameDlgVis(false)}>
                <div className='change_servername'>
                    <div className="change_servername_body">
                        
                        <div className="server_avatar_preview">
                            {/* <div className="avatar_placeholder"> {serverName ? serverName[0] : 'S'} </div> */}
                        </div>
                        
                        <div className="input_group">
                            <label htmlFor="server_name">群组名称</label>
                            <MyInput 
                                value={newServerName} 
                                id='server_name'
                                onChange={setNewServerName}
                                type='text'
                                placeholder="输入群组名称"
                            />
                        </div>
                    </div>

                    <div className="change_servername_footer">
                        <MyButton 
                            name='确定' 
                            type='primary'
                            onClick={changeServerName}
                        />
                    </div>

                </div>
            </MyDialog>
            <ConfirmDialog 
                visible={exitServerDlgVis} 
                onClose={()=>setExitServerDlgVis(false)} 
                onConfirm={exitServer}
                tipText={userServerInfo?.role=='owner'?`此操作将删除该群组，你确定吗？`:`确定要离开${userServerInfo?.server_name}群组吗？`}
                confirmText={userServerInfo?.role=='owner'?'确认释放群组':'离开群组'}
            />
            <CreateChannel visible={addChannelDlgVis} onClose={()=>setAddChannelDlgVis(false)} onRefresh={getChannelList}></CreateChannel>
        </>
    )
}

export default Channel;